package com.sc.nft.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.SelfAmmunitionDao;
import com.sc.nft.dto.CreateSelfAmmunitionPageDTO;
import com.sc.nft.dto.EditSelfAmmunitionPageDTO;
import com.sc.nft.entity.ActivityBasics;
import com.sc.nft.entity.SelfAmmunition;
import com.sc.nft.entity.UserInfo;
import com.sc.nft.entity.vo.SelfAmmunitionDetailVO;
import com.sc.nft.entity.vo.SelfAmmunitionPageVO;
import com.sc.nft.entity.vo.SelfAmmunitionShowVO;
import com.sc.nft.entity.vo.SelfAmmunitionVO;
import com.sc.nft.enums.JumpTypeEnum;
import com.sc.nft.enums.JumpTypeSeflAmmunitionEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.ActivityBasicsService;
import com.sc.nft.service.SelfAmmunitionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.sc.nft.enums.RedisKeyEnum.SELF_AMMUNITION_IMG;
import static com.sc.nft.enums.RedisKeyEnum.USER_REQUEST_SELF_AMMUNITION_IMG;

/**
 * @author 张超
 * @description 针对表【sc_self_ammunition(自弹活动引导图)】的数据库操作Service实现
 * @createDate 2024-06-04 13:29:51
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class SelfAmmunitionServiceImpl implements SelfAmmunitionService {

    private final SelfAmmunitionDao selfAmmunitionDao;
    private final ActivityBasicsService activityBasicsService;
    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public IPage<SelfAmmunitionPageVO> selfAmmunitionPage(Page mp) {
        IPage<SelfAmmunitionPageVO> selfAmmunitionPageVOIPage = selfAmmunitionDao.selfAmmunitionPage(mp);
        List<SelfAmmunitionPageVO> records = selfAmmunitionPageVOIPage.getRecords();
        if (ObjectUtil.isNotEmpty(records)) {
            records.forEach(selfAmmunitionPageVO -> {
                if (ObjectUtil.isNotNull(selfAmmunitionPageVO.getJumpId()) && selfAmmunitionPageVO.getJumpId().getCode() != JumpTypeSeflAmmunitionEnum.ACTIVITY_ZONE.getCode()) {
                    selfAmmunitionPageVO.setJumpUrl(selfAmmunitionPageVO.getJumpId().getDesc());
                }
            });
        }
        return selfAmmunitionPageVOIPage;
    }

    @Override
    public void selfAmmunitionAdd(CreateSelfAmmunitionPageDTO selfAmmunitionPageDTO) {
        SelfAmmunition selfAmmunition = new SelfAmmunition();
        selfAmmunition.setActivityId(selfAmmunitionPageDTO.getActivityId());
        selfAmmunition.setSelfAmmunitionImg(selfAmmunitionPageDTO.getSelfAmmunitionImg());
        selfAmmunition.setSelfAmmunitionName(selfAmmunitionPageDTO.getSelfAmmunitionName());
        selfAmmunition.setJumpType(selfAmmunitionPageDTO.getJumpType().getCode());
        selfAmmunition.setJumpId(selfAmmunitionPageDTO.getJumpId());

        if (JumpTypeEnum.SELF_APP.getCode() == selfAmmunitionPageDTO.getJumpType().getCode()) {
            if (selfAmmunitionPageDTO.getJumpId().equals(12L)) {
                ActivityBasics activityBasicsServiceById = activityBasicsService.getById(selfAmmunitionPageDTO.getActivityId());
                selfAmmunition.setJumpUrl("活动专区" + " -【" + activityBasicsServiceById.getNameActivity() + "】");
            }
            selfAmmunition.setRichText(selfAmmunitionPageDTO.getJumpUrl());
        } else {
            selfAmmunition.setJumpUrl(selfAmmunitionPageDTO.getJumpUrl());
        }

        selfAmmunition.setIsListing(Boolean.FALSE);
        selfAmmunition.setRemark(selfAmmunitionPageDTO.getRemark());
        selfAmmunition.setSelfAmmunitionStartTime(selfAmmunitionPageDTO.getSelfAmmunitionStartTime());
        selfAmmunition.setSelfAmmunitionEndTime(selfAmmunitionPageDTO.getSelfAmmunitionEndTime());
        selfAmmunition.setSort(selfAmmunitionPageDTO.getSort());
        selfAmmunition.setSelfType(selfAmmunitionPageDTO.getSelfType().getCode());

        Integer count = selfAmmunitionDao.checkSelfAmmunitionSelfAmmunitionName(selfAmmunition.getSelfAmmunitionName(), selfAmmunition.getJumpType().getCode(), null);
        Assert.isFalse(ObjectUtil.isNotNull(count) && Convert.toInt(count) >= 1, () -> new GlobalRunTimeException("名称已存在"));
        selfAmmunition.setIsListing(Boolean.FALSE);
        Assert.isTrue(selfAmmunition.insert(), () -> new GlobalRunTimeException("新增失败！"));
    }

    @Override
    public void selfAmmunitionUpdate(EditSelfAmmunitionPageDTO selfAmmunitionPageDTO) {
        SelfAmmunition selfAmmunition = new SelfAmmunition();
        selfAmmunition.setId(selfAmmunitionPageDTO.getId());
        selfAmmunition.setActivityId(selfAmmunitionPageDTO.getActivityId());
        selfAmmunition.setSelfAmmunitionImg(selfAmmunitionPageDTO.getSelfAmmunitionImg());
        selfAmmunition.setSelfAmmunitionName(selfAmmunitionPageDTO.getSelfAmmunitionName());
        selfAmmunition.setJumpType(selfAmmunitionPageDTO.getJumpType().getCode());
        selfAmmunition.setJumpId(selfAmmunitionPageDTO.getJumpId());

        //12L是活动中心
        if (JumpTypeEnum.SELF_APP.getCode() == selfAmmunitionPageDTO.getJumpType().getCode()) {
            if (selfAmmunitionPageDTO.getJumpId().equals(12L)) {
                ActivityBasics activityBasicsServiceById = activityBasicsService.getById(selfAmmunitionPageDTO.getActivityId());
                selfAmmunition.setJumpUrl("活动专区" + " -【" + activityBasicsServiceById.getNameActivity() + "】");
            }
            selfAmmunition.setRichText(selfAmmunitionPageDTO.getJumpUrl());
        } else {
            selfAmmunition.setJumpUrl(selfAmmunitionPageDTO.getJumpUrl());
        }

        selfAmmunition.setIsListing(Boolean.FALSE);
        selfAmmunition.setRemark(selfAmmunitionPageDTO.getRemark());
        selfAmmunition.setSelfAmmunitionStartTime(selfAmmunitionPageDTO.getSelfAmmunitionStartTime());
        selfAmmunition.setSelfAmmunitionEndTime(selfAmmunitionPageDTO.getSelfAmmunitionEndTime());
        selfAmmunition.setSort(selfAmmunitionPageDTO.getSort());
        selfAmmunition.setSelfType(selfAmmunitionPageDTO.getSelfType().getCode());

        SelfAmmunition selfAmmunitionDaoById = selfAmmunitionDao.getById(selfAmmunition.getId());
        Assert.notNull(selfAmmunitionDaoById, () -> new GlobalRunTimeException("该自弹不存在！"));
        Assert.isTrue(selfAmmunition.getSelfAmmunitionStartTime().before(selfAmmunition.getSelfAmmunitionEndTime()), () -> new GlobalRunTimeException("开始时间需要大于结束时间"));
        Integer count = selfAmmunitionDao.checkSelfAmmunitionSelfAmmunitionName(selfAmmunition.getSelfAmmunitionName(), selfAmmunition.getJumpType().getCode(), selfAmmunition.getId());
        Assert.isFalse(ObjectUtil.isNotNull(count) && Convert.toInt(count) >= 1, () -> new GlobalRunTimeException("名称已存在"));
        Assert.isFalse(Boolean.TRUE.equals(selfAmmunitionDaoById.getIsListing()), () -> new GlobalRunTimeException("上架的自弹不支持修改！"));
        Assert.isTrue(selfAmmunitionDao.selfAmmunitionUpdate(selfAmmunition), () -> new GlobalRunTimeException("修改失败！"));
    }

    @Override
    public SelfAmmunitionDetailVO selfAmmunitionDetail(Long id) {
        SelfAmmunition selfAmmunitionDaoById = selfAmmunitionDao.getById(id);
        Assert.notNull(selfAmmunitionDaoById, () -> new GlobalRunTimeException("该自弹不存在！"));

        SelfAmmunitionDetailVO selfAmmunition = selfAmmunitionDao.selfAmmunitionDetail(id);
        selfAmmunition.setJumpUrl(Convert.toStr(selfAmmunition.getRichText()));
        if (JumpTypeEnum.SELF_APP.getCode() == selfAmmunitionDaoById.getJumpType().getCode()) {
            selfAmmunition.setJumpUrl(Convert.toStr(selfAmmunition.getRichText()));
        } else {
            selfAmmunition.setJumpUrl(selfAmmunitionDaoById.getJumpUrl());
        }

        return selfAmmunition;
    }

    @Override
    public void selfAmmunitionIsListing(Long id, Boolean status) {
        SelfAmmunition selfAmmunitionDaoById = selfAmmunitionDao.getById(id);
        Assert.notNull(selfAmmunitionDaoById, () -> new GlobalRunTimeException("该自弹不存在！"));
        //上架的时候需要判断是否超过五个上架的
        if (status) {
            Integer count = selfAmmunitionDao.checkSelfAmmunitionIsListing();
            Assert.isFalse(Convert.toInt(count) >= 5, () -> new GlobalRunTimeException("上架数量已达到上限"));
        }
        Assert.isTrue(selfAmmunitionDao.selfAmmunitionIsListing(id, status), () -> new GlobalRunTimeException("修改失败！"));



        //保存展示的引导图到redis 五个 当前时间大于结束时间 未开始
        List<SelfAmmunitionVO> selfAmmunitionVOList = selfAmmunitionDao.getSelfAmmunitionIsListing();
        //jumpUrl = richText  id = jumpId
        if (ObjectUtil.isNotEmpty(selfAmmunitionVOList)) {
            selfAmmunitionVOList.forEach(selfAmmunitionVO -> {
                selfAmmunitionVO.setId(selfAmmunitionVO.getJumpId());
                if (ObjectUtil.isNotEmpty(selfAmmunitionVO.getRichText())) {
                    selfAmmunitionVO.setJumpUrl(selfAmmunitionVO.getRichText());
                }
            });
            //清空 重新放展示引导图
            String selfAmmunitionImg = SELF_AMMUNITION_IMG.getKey();
            redisTemplate.delete(selfAmmunitionImg);
            redisTemplate.opsForValue().set(selfAmmunitionImg, JSONObject.toJSON(selfAmmunitionVOList).toString());

            //保存多长时间 获取最大的活动时间为过期时间
            List<SelfAmmunitionVO> selfAmmunitionVOS = selfAmmunitionVOList.stream().sorted(Comparator.comparing(SelfAmmunitionVO::getSelfAmmunitionEndTime)).collect(Collectors.toList());
            Date selfAmmunitionEndTime = selfAmmunitionVOS.get(0).getSelfAmmunitionEndTime();

            long expirationTime = DateUtil.between(new Date(), selfAmmunitionEndTime, DateUnit.SECOND);
            redisTemplate.expire(selfAmmunitionImg, expirationTime, TimeUnit.SECONDS);
        }

    }

    @Override
    public void selfAmmunitionDelete(Long id) {
        SelfAmmunition selfAmmunitionDaoById = selfAmmunitionDao.getById(id);
        Assert.notNull(selfAmmunitionDaoById, () -> new GlobalRunTimeException("该自弹不存在！"));
        Assert.isFalse(Boolean.TRUE.equals(selfAmmunitionDaoById.getIsListing()), () -> new GlobalRunTimeException("上架的自弹不支持修改！"));
        Assert.isTrue(selfAmmunitionDao.selfAmmunitionDelete(id), () -> new GlobalRunTimeException("删除失败！"));


        List<SelfAmmunitionVO> selfAmmunitionVOList = selfAmmunitionDao.getSelfAmmunitionIsListing();
        //清空 重新放展示引导图
        String selfAmmunitionImg = SELF_AMMUNITION_IMG.getKey();
        redisTemplate.delete(selfAmmunitionImg);
        redisTemplate.opsForValue().set(selfAmmunitionImg, JSONObject.toJSON(selfAmmunitionVOList).toString());

        //保存多长时间 获取最大的活动时间为过期时间
        List<SelfAmmunitionVO> selfAmmunitionVOS = selfAmmunitionVOList.stream().sorted(Comparator.comparing(SelfAmmunitionVO::getSelfAmmunitionEndTime)).collect(Collectors.toList());
        Date selfAmmunitionEndTime = selfAmmunitionVOS.get(0).getSelfAmmunitionEndTime();

        long expirationTime = DateUtil.between(new Date(), selfAmmunitionEndTime, DateUnit.SECOND);
        redisTemplate.expire(selfAmmunitionImg, expirationTime, TimeUnit.SECONDS);
    }


    @Override
    public SelfAmmunitionShowVO selfAmmunitionImg(int jumpType, UserInfo user) {
        String selfAmmunition = USER_REQUEST_SELF_AMMUNITION_IMG.getKey() + user.getId();
        String selfAmmunitionImg = SELF_AMMUNITION_IMG.getKey();

        //获取需要展示的引导图
        String selfAmmunitionString = (String) redisTemplate.opsForValue().get(selfAmmunitionImg);
        if (StrUtil.isBlank(selfAmmunitionString)) {
            return null;
        }
        List<SelfAmmunitionShowVO> selfAmmunitionImgList = JSONObject.parseArray(selfAmmunitionString, SelfAmmunitionShowVO.class);

        if (ObjectUtil.isEmpty(selfAmmunitionImgList)) {
            return null;
        }

        //按照sort排序
        List<SelfAmmunitionShowVO> selfAmmunitionVOList = selfAmmunitionImgList.stream().sorted(Comparator.comparing(SelfAmmunitionShowVO::getSort).reversed()).collect(Collectors.toList());
        if (CollUtil.isEmpty(selfAmmunitionVOList)) {
            return null;
        }

        //按照请求次数拿到下标
        Boolean userRequestExist = redisTemplate.hasKey(selfAmmunition);

        //获取当前时间距离下一天还有多少
        Date nowStartDate = new Date();
        DateTime nowEndDate = DateUtil.endOfDay(nowStartDate);
        long between = DateUtil.between(nowStartDate, nowEndDate, DateUnit.SECOND);
        Long requestCount = redisTemplate.opsForValue().increment(selfAmmunition);
        redisTemplate.expire(selfAmmunition, between, TimeUnit.SECONDS);

        Date date = new Date();
        if (!Boolean.TRUE.equals((userRequestExist))) {
            //判断活动时间是否有效
            SelfAmmunitionShowVO selfAmmunitionVO = selfAmmunitionVOList.get(0);

            //活动中心才有activityId 详情Id 12代表活动中心
            if (Objects.equals(selfAmmunitionVO.getJumpType(), JumpTypeEnum.SELF_APP) && ObjectUtil.isNotNull(selfAmmunitionVO.getJumpId()) && selfAmmunitionVO.getJumpId().equals(12L)) {
                //活动类型和Id
                ActivityBasics activityBasics = activityBasicsService.getById(selfAmmunitionVO.getActivityId());
                selfAmmunitionVO.setJumpUrl(Convert.toStr(activityBasics.getId()));
                selfAmmunitionVO.setType(activityBasics.getType());
                selfAmmunitionVO.setId(selfAmmunitionVO.getJumpId());
            }

            if (selfAmmunitionVO.getSelfAmmunitionEndTime().after(date)) {
                selfAmmunitionVO.setId(selfAmmunitionVO.getJumpId());
                return selfAmmunitionVO;
            } else {
                return null;
            }
        } else {
            //还存在需要弹出的引导图
            if (selfAmmunitionVOList.size() >= requestCount) {
                SelfAmmunitionShowVO selfAmmunitionShowVO = selfAmmunitionVOList.get(Math.toIntExact(requestCount - 1));
                if (selfAmmunitionShowVO.getSelfAmmunitionEndTime().after(date)) {
                    //如果是活动中心的页面
                    if (Objects.equals(selfAmmunitionShowVO.getJumpType(), JumpTypeEnum.SELF_APP) && ObjectUtil.isNotNull(selfAmmunitionShowVO.getJumpId()) && selfAmmunitionShowVO.getJumpId().equals(12L)) {
                        ActivityBasics activityBasics = activityBasicsService.getById(selfAmmunitionShowVO.getActivityId());
                        selfAmmunitionShowVO.setJumpUrl(Convert.toStr(activityBasics.getId()));
                        selfAmmunitionShowVO.setType(activityBasics.getType());
                        selfAmmunitionShowVO.setId(selfAmmunitionShowVO.getJumpId());
                    }
                    return selfAmmunitionShowVO;
                } else {
                    return null;
                }
            }
        }
        return null;
    }

}




